package com.xhs.utils;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

/**
 * @desc: Rsa加解密
 * @projectName: tools-parent
 * @author: xhs
 * @date: 2023-6-4 004 20:29
 * @version: JDK 1.8
 */
@Slf4j
public class RsaUtil {

    /**
     * 私钥解密
     *
     * @param beforeEncryption 加密
     * @return
     */
    public static String encryption(String beforeEncryption) {
        KeyPair pair = SecureUtil.generateKeyPair("RSA");
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();

        //获得私钥
        String privateKeyStr = bytesToBase64(privateKey.getEncoded());
        log.info("[私钥]:[{}]", privateKeyStr);
        //获得公钥
        String publicKeyStr = bytesToBase64(publicKey.getEncoded());
        log.info("[公钥]:[{}]", publicKeyStr);

        RSA rsa = new RSA(privateKeyStr, publicKeyStr);
        log.info("[rsa]:[{}]", rsa);

        //公钥加密，私钥解密
        byte[] encrypt = rsa.encrypt(StrUtil.bytes(beforeEncryption, CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
        log.info("[私钥解密]:[{}]", bytesToBase64(encrypt));

        byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
        log.info("[私钥解密]:[{}]", new String(decrypt, StandardCharsets.UTF_8));
        return bytesToBase64(encrypt);
    }


    /**
     * 私钥解密
     *
     * @param afterEncryption 解密字符串
     * @param privateKeyStr   私钥
     * @return
     */
    public static String decrypt(String afterEncryption, String privateKeyStr) {
        String publicKeyStr = "";
        RSA rsa = new RSA(privateKeyStr, publicKeyStr);
        log.info("[rsa]:[{}]", rsa);
        String replaceAll = afterEncryption.replaceAll(" +", "+");
        byte[] decrypt = rsa.decrypt(base64ToBytes(replaceAll), KeyType.PrivateKey);
        log.info("[私钥解密]:[{}]", new String(decrypt, StandardCharsets.UTF_8));
        return new String(decrypt, StandardCharsets.UTF_8);
    }

    /**
     * 字节数组转Base64编码
     *
     * @param bytes 字节数组
     * @return Base64编码
     */
    private static String bytesToBase64(byte[] bytes) {
        byte[] encodedBytes = Base64.getEncoder().encode(bytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * Base64编码转字节数组
     *
     * @param base64Str Base64编码
     * @return 字节数组
     */
    private static byte[] base64ToBytes(String base64Str) {
        byte[] bytes = base64Str.getBytes(StandardCharsets.UTF_8);
        return Base64.getDecoder().decode(bytes);
    }
}
